home *** CD-ROM | disk | FTP | other *** search
- Impurity-1.0
- by Alexander E. Cuttergo <cuttergo@gmx.net>
-
- Concept
- Impurity is a set of scripts which make it easy to produce a
- shellcode ("first stage") which is able to download over the net an
- executable ELF file ("second stage") and execute it without writing it to
- the disk first. The first stage shellcode itself is almost constant (except
- for one parameter, the executable length) and very short - 46 bytes. Using
- this approach, one does not waste hours composing and debugging a complex
- shellcode - just write a .c program, run impurity (which creates the second
- stage ELF binary) and you are all set.
- Impurity is mostly useful when exploiting a daemon which runs
- chrooted and with dropped privileges; in such case one cannot simply execute
- /bin/sh. Compare it with MOSDEF and InlineEgg.
- Currently impurity is implemented for Linux/i386 only; however,
- porting to other OS/architectures should be trivial, provided they use ELF
- standard.
-
- License
- GPL v2
-
- Theory of operation
- In order to be able to execute an ELF binary easily, we will have to
- compile it (more precisely, link it) in a special way.
- 1) In order to not be troubled by shared libraries, we will link the binary
- statically.
- 2) An usual executable text segment is mapped at 0x8048000. In our case,
- this area is occupied by the text segment of an overflown binary. We could
- unmap() it, but this would make our shellcode unnecessarily large. The
- solution - use a linker script which will place the text segment starting at
- different address. We will use 0xbfff1000 - it is within the stack, so all
- we need to allocate memory for our executable is to do
- "movl $0xbfff1000, %esp". This also means we will need an executable stack -
- this should not be a problem usually. Enhancing shellcode in a way which
- allocates memory for our ELF by mmap(...,PROT_EXEC,...) is left as an
- excercise for a reader.
- Moreover, in order to consequently simplify our first stage shellcode,
- command line arguments and environment are not set, dereferencing them will
- cause a SIGSEGV most likely. It is easily fixable in the second stage itself
- (see tracepath.c example).
- 3) In a normal executable, the text and data segments are in disjoint memory
- areas, with different permissions. This again complicates the loading
- process. To avoid it, we will link our ELF executable as impure executable
- (ld -N).
- 4) Binaries linked statically with recent glibc are large. This is usually
- not a problem - during the bruteforcing stage of an exploit, we do not need
- to send the binary at all to determine whether the correct offset has been
- found. Anyway, "diet libc" is recommended - small programs linked with diet
- libc are usually in 2k-30k size range. The provided shellcode (bootcode.S)
- uses an unsigned short to store the executable length, thus limiting the
- ELF binary to 64k (bla bla excercise for a reader bla).
- 5) The first stage shellcode downloads the second stage ELF binary from file
- descriptor 0. It should not be difficult to add code which utilizes "find
- socket shellcode", or just creates appropriate socket itself. Excercise,
- reader, make bucks by selling this enhancement, bla.
-
- Having 1-5 in mind, executing an ELF is really simple - just read
- appropriate number of bytes from fd 0 into memory starting at 0xbfff1000,
- and then jump to 0xbfff1074, where the entry point should be. Execve()
- demystified ;)
-
- Provided code
- bootcode.S - first stage shellcode
- bootstrap.c - trivial stub which emits to stdout asm from bootcode.S,
- adjusting file length u16 in its body
- filesize.c - a helper which prints the file size to stdout
- script-ld-impure-into-stack - a proper ld script
- tracepath.c - a sample second stage. It is almost a verbatim copy of
- tracepath.c from iputils; the only changes are a few lines to
- prepare a command line and environment.
- shelix.c - a sample program, vulnerable to a buffer overflow. It does
- chroot(/var/empty) and setuid(12345), so we cannot break out of chroot nor
- execute /bin/sh; also we have no writeable directory to download any
- executable to. As an example, we use impurity to produce a second stage
- based on tracepath, hoping to learn the DMZ layout. Yes, we can use nmap (or
- linux_autorooter.0227) as the second stage easily.
-
- Running a sample code
- You have to install diet libc (http://www.fefe.de/dietlibc/) first.
- 1) Run "make"
- 2) Run "shelix" as root via [x]inetd or "nc -l -p shelix_port -e ./shelix"
- 3) "make" produces "ovdata" file, which contains buffer overflow payload and
- the first stage shellcode, so:
- $ (cat ovdata ; sleep 1; cat tracepath; cat) | nc localhost shelix_port
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 2
- Shelix: got token length 46
- Second stage OK. Which ipaddr should I try ?
- c.d.40.1 <- entered from stdin
- 1?: [LOCALHOST] pmtu 1500
- 1: x.y.131.57 2.127ms
- 2?: x.y.20.176
- 3?: a.b.40.5
- 4?: c.d.40.1
- Resume: pmtu 1500 hops 4 back 4
-
- Again, if you want to use a different second stage, all you need is to compile
- its sources instead of tracepath.c . If attacking a different vulnerable
- daemon, you will need to change the overflow payload creation ("ovdata"
- target in Makefile), but no need to touch any assembly.
-